package com.meilai.project.service.business.customer.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilai.project.dto.business.customer.CustomerEditDTO;
import com.meilai.project.dto.workflow.FlowBusinessDataSuperEntity;
import com.meilai.project.dto.workflow.WorkFlowCheckDTO;
import com.meilai.project.entity.business.customer.*;
import com.meilai.project.exception.CommonException;
import com.meilai.project.mapper.business.customer.CustomerEditFlowMapper;
import com.meilai.project.service.business.customer.*;
import com.meilai.project.service.business.dataLevel.DataQueryBusinessLevelService;
import com.meilai.project.util.ThreadLocalUserUtil;
import com.meilai.project.util.WorkFlowUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xhy
 * @since 2022-01-13
 */
@Service
public class CustomerEditFlowImpl extends ServiceImpl<CustomerEditFlowMapper, CustomerEditFlow> implements CustomerEditFlowService {
    @Autowired
    private CustomerInfoService customerInfoService;
    @Autowired
    private CustomerFunnelService customerFunnelService;
    @Autowired
    private CustomerSelectionReasonService customerSelectionReasonService;
    @Autowired
    private CustomerEditFunnelTmpService customerEditFunnelTmpService;
    @Autowired
    private CustomerEditSelectionReasonTmpService customerEditSelectionReasonTmpService;
    @Autowired
    private CustomerPutStorageEditTmpService customerPutStorageEditTmpService;
    @Autowired
    private CustomerContactEditTmpService customerContactEditTmpService;
    @Autowired
    private CustomerContactService customerContactService;
    @Autowired
    private CustomerPutStorageService customerPutStorageService;

    @Autowired
    private DataQueryBusinessLevelService dataQueryBusinessLevelService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveDrafts(CustomerEditDTO dto, boolean flag, Long wfData_id) {
        Long userId = ThreadLocalUserUtil.get().getId();
        if (!flag) {
            Boolean f = customerInfoService.queryCustomerFlow(dto.getCustomer_id());
            if (!f) {
                throw new CommonException("此客户有审核信息在流程中");
            }
        }
        int level = dataQueryBusinessLevelService.getUserMaxLevel("customer_contact", userId);
        Long main_department_id = ThreadLocalUserUtil.get().getMain_department_id();
        CustomerEditFlow flow = new CustomerEditFlow();
        BeanUtils.copyProperties(dto, flow);//复制业务数据
        FlowBusinessDataSuperEntity startSuperDataEntity = WorkFlowUtil.getStartSuperDataEntity(userId, main_department_id, 7, dto.getName() + "客户信息变更");
        BeanUtils.copyProperties(startSuperDataEntity, flow);
        flow.setId(dto.getId());
        Boolean b = flow.getId() == null;
        Boolean tmp = this.saveOrUpdate(flow);
        int result = -1;
        if (flag && b) {
            result = wfData_id == null ? new WorkFlowUtil<CustomerEditFlow, CustomerEditFlowMapper>(flow.getId(), userId, CustomerEditFlow.class).SaveDraft(-1L) : new WorkFlowUtil<CustomerEditFlow, CustomerEditFlowMapper>(flow.getId(), userId, CustomerEditFlow.class).SaveDraft(wfData_id);
        } else {
            result = 1;
        }
        if (b) {
            dto.setId(flow.getId());
        }
        customerEditFunnelTmpService.remove(Wrappers.<CustomerEditFunnelTmp>lambdaQuery().eq(CustomerEditFunnelTmp::getCustomer_edit_flow_id, dto.getId()));
        customerEditSelectionReasonTmpService.remove(Wrappers.<CustomerEditSelectionReasonTmp>lambdaQuery().eq(CustomerEditSelectionReasonTmp::getCustomer_edit_flow_id, dto.getId()));
        customerContactEditTmpService.remove(Wrappers.<CustomerContactEditTmp>lambdaQuery().eq(CustomerContactEditTmp::getCustomer_edit_flow_id, dto.getId()));
        customerPutStorageEditTmpService.remove(Wrappers.<CustomerPutStorageEditTmp>lambdaQuery().eq(CustomerPutStorageEditTmp::getCustomer_edit_flow_id, dto.getId()));
        customerPutStorageEditTmpService.saveBatch(
                dto.getPutStorageList().stream().map(
                        item -> {
                            CustomerPutStorageEditTmp customerPutStorageEditTmp = new CustomerPutStorageEditTmp();
                            BeanUtils.copyProperties(item, customerPutStorageEditTmp);
                            customerPutStorageEditTmp.setId(null);
                            customerPutStorageEditTmp.setCustomer_edit_flow_id(flow.getId());
                            return customerPutStorageEditTmp;
                        }
                ).collect(Collectors.toList())
        );
        customerEditFunnelTmpService.saveBatch(
                dto.getFunnels().stream().map(item -> {
                            CustomerEditFunnelTmp funnelTmp = new CustomerEditFunnelTmp();
                            funnelTmp.setCustomer_edit_flow_id(flow.getId());
                            funnelTmp.setFunnel_type_id(item);
                            return funnelTmp;
                        }
                ).collect(Collectors.toList())
        );
        customerEditSelectionReasonTmpService.saveBatch(
                dto.getSelection_reasons().stream().map(item -> {
                            CustomerEditSelectionReasonTmp reasonTmp = new CustomerEditSelectionReasonTmp();
                            reasonTmp.setCustomer_edit_flow_id(flow.getId());
                            reasonTmp.setSelection_reason_id(item);
                            return reasonTmp;
                        }
                ).collect(Collectors.toList()));
        customerContactEditTmpService.saveBatch(
                dto.getContactsList().stream().map(
                        item -> {
                            CustomerContactEditTmp customerContactEditTmp = new CustomerContactEditTmp();
                            BeanUtils.copyProperties(item, customerContactEditTmp);
                            customerContactEditTmp.setId(null);
                            if (customerContactEditTmp.getLevel_num() == null) {
                                customerContactEditTmp.setLevel_num(level);
                            }
                            customerContactEditTmp.setCustomer_edit_flow_id(flow.getId());
                            return customerContactEditTmp;
                        }
                ).collect(Collectors.toList()));
        return result == 1 && tmp;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveAndStartFlow(CustomerEditDTO dto, Long wfData_id) {
        Long userId = ThreadLocalUserUtil.get().getId();
        CustomerEditFlow flow = new CustomerEditFlow();
        BeanUtils.copyProperties(dto, flow);
        return this.saveDrafts(dto, false, null) && new WorkFlowUtil<CustomerEditFlow, CustomerEditFlowMapper>(dto.getId(), userId, CustomerEditFlow.class).Begin(wfData_id == null ? -1 : wfData_id, "", flow) == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean check(CustomerEditDTO dto, Boolean isReturn, String opinion) {
        Long userId = ThreadLocalUserUtil.get().getId();
        CustomerEditFlow flow = new CustomerEditFlow();
        BeanUtils.copyProperties(dto, flow);
        Long curCheckIndex = WorkFlowUtil.getCurCheckIndex(flow.getFlow_json(), flow.getFlow_current_node_id());
        int result = -1;
        if (isReturn) {//如果是通过
            result = new WorkFlowUtil<CustomerEditFlow, CustomerEditFlowMapper>(dto.getId(), userId, CustomerEditFlow.class).ToNext(new WorkFlowCheckDTO(flow.getFlow_current_node_id(), curCheckIndex, opinion, ""));
        } else {
            result = new WorkFlowUtil<CustomerEditFlow, CustomerEditFlowMapper>(dto.getId(), userId, CustomerEditFlow.class).ReturnBack(new WorkFlowCheckDTO(flow.getFlow_current_node_id(), curCheckIndex, opinion, ""));
        }
        if (result == 1) {
            return true;
        } else if (result == 2) {
            CustomerInfo info = new CustomerInfo();
            BeanUtils.copyProperties(dto, info);
            info.setId(dto.getCustomer_id());
            info.setCreated_at(null);
            customerFunnelService.remove(Wrappers.<CustomerFunnel>lambdaQuery().eq(CustomerFunnel::getCustomer_id, info.getId()));
            customerSelectionReasonService.remove(Wrappers.<CustomerSelectionReason>lambdaQuery().eq(CustomerSelectionReason::getCustomer_id, info.getId()));
            customerContactService.remove(Wrappers.<CustomerContact>lambdaQuery().eq(CustomerContact::getCustomer_id, info.getId()));
            customerPutStorageService.remove(Wrappers.<CustomerPutStorage>lambdaQuery().eq(CustomerPutStorage::getCustomer_id, info.getId()));
            customerInfoService.updateById(info);
            customerFunnelService.saveBatch(
                    dto.getFunnels().stream().map(item -> {
                        CustomerFunnel funnel = new CustomerFunnel();
                        funnel.setCustomer_id(info.getId());
                        funnel.setFunnel_type_id(item);
                        return funnel;
                    }).collect(Collectors.toList()));
            customerSelectionReasonService.saveBatch(
                    dto.getSelection_reasons().stream().map(
                            item -> {
                                CustomerSelectionReason selectionReason = new CustomerSelectionReason();
                                selectionReason.setCustomer_id(info.getId());
                                selectionReason.setSelection_reason_id(item);
                                return selectionReason;
                            }
                    ).collect(Collectors.toList()));
            customerContactService.saveBatch(
                    dto.getContactsList().stream().map(
                            item -> {
                                CustomerContact customerContact = new CustomerContact();
                                BeanUtils.copyProperties(item, customerContact);
                                customerContact.setId(null);
                                customerContact.setCustomer_id(info.getId());
                                return customerContact;
                            }
                    ).collect(Collectors.toList())
            );
            customerPutStorageService.saveBatch(
                    dto.getPutStorageList().stream().map(
                            item -> {
                                CustomerPutStorage customerPutStorage = new CustomerPutStorage();
                                BeanUtils.copyProperties(item, customerPutStorage);
                                customerPutStorage.setId(null);
                                customerPutStorage.setCustomer_id(info.getId());
                                return customerPutStorage;
                            }
                    ).collect(Collectors.toList())
            );
            return true;
        } else {
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean remove(Long flow_id, Long wf_data_id) {
        Long userId = ThreadLocalUserUtil.get().getId();
        return new WorkFlowUtil<CustomerEditFlow, CustomerEditFlowMapper>(flow_id, userId, CustomerEditFlow.class).Delete(wf_data_id) == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean actualDelete(Long flow_id, Long wf_data_id) {
        Long userId = ThreadLocalUserUtil.get().getId();
        return new WorkFlowUtil<CustomerEditFlow, CustomerEditFlowMapper>(flow_id, userId, CustomerEditFlow.class).ActualDelete(wf_data_id) == 1;
    }

    @Override
    public CustomerEditDTO getDtoById(Long flow_id) {
        Long userId = ThreadLocalUserUtil.get().getId();
        CustomerEditDTO dto = baseMapper.getDtoById(flow_id);
        CustomerEditFlow flow = new CustomerEditFlow();
        BeanUtils.copyProperties(dto, flow);
        dto.setCheck(WorkFlowUtil.canCheckData(userId, flow));
        int level = dataQueryBusinessLevelService.getUserMaxLevel("customer_contact", userId);
        List<CustomerContactEditTmp> contactTmpList = customerContactEditTmpService.list(Wrappers.<CustomerContactEditTmp>lambdaQuery().eq(CustomerContactEditTmp::getCustomer_edit_flow_id, dto.getId()));
        if (CollectionUtils.isNotEmpty(contactTmpList)) {
            contactTmpList.forEach(customerContactEditTmp -> {
                if (level != -1 && level <= customerContactEditTmp.getLevel_num()) {
                    customerContactEditTmp.setCan_look(true);
                }
            });
        }
        List<CustomerPutStorageEditTmp> customerPutStorageTmpList = customerPutStorageEditTmpService.list(Wrappers.<CustomerPutStorageEditTmp>lambdaQuery().eq(CustomerPutStorageEditTmp::getCustomer_edit_flow_id, dto.getId()));
        dto.setPutStorageList(customerPutStorageTmpList);
        dto.setContactsList(contactTmpList);
        return dto;
    }
}
